﻿<%@ Page Culture="auto" UICulture="auto" Title="Writing custom value handlers" Language="C#"
    MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CustomValueHandler.aspx.cs"
    Inherits="BM.Tools.WebControls.MForm.Example.ValueHandlers.CustomValueHandler" %>

<%@ Register TagPrefix="mf" Namespace="BM.Tools.WebControls.MForm.Controls" Assembly="BM.Tools.WebControls.MForm" %>
<%@ Register TagPrefix="mfadd" Namespace="BM.Tools.WebControls.MForm.Controls.Additions"
    Assembly="BM.Tools.WebControls.MForm" %>
<%@ Register TagPrefix="mfmod" Namespace="BM.Tools.WebControls.MForm.Controls.Modifiers"
    Assembly="BM.Tools.WebControls.MForm" %>
<%@ Register TagPrefix="mfvh" Namespace="BM.Tools.WebControls.MForm.Controls.ValueHandlers"
    Assembly="BM.Tools.WebControls.MForm" %>
<%@ Register TagPrefix="zh" Namespace="BM.Tools.WebControls.MForm.Example.ValueHandlers"
    Assembly="BM.Tools.WebControls.MForm.Example" %>
<%@ Register TagPrefix="mftitle" Namespace="BM.Tools.WebControls.MForm.Controls.Titles"
    Assembly="BM.Tools.WebControls.MForm" %>
<asp:Content ContentPlaceHolderID="Demonstration" runat="server">
    <p>
        In the following example, the <code>ZipCodeValueHandler</code> is created. The handler
        is created for the <code>ZipCodeControl</code>. This control accepts a zip code
        of the following format (two digits)-(three digits). There are separate textboxes
        for two digits and for three digits. The dash between the digits is added automatically.
    </p>
    <mf:RootValidator runat="server" ControlToValidate="Root1" />
    <mf:Root ID="Root1" runat="server">
        <Contents>
            <mf:Branch Name="Address" runat="server" meta:resourcekey="Address">
                <Contents>
                    <mf:Leaf Name="Street" runat="server" meta:resourcekey="Address_Street">
                        <Additions>
                            <mfadd:Restriction runat="server" RestrictionType="MaxLength" Value="100" />
                        </Additions>
                    </mf:Leaf>
                    <mf:Leaf Name="HouseNumber" runat="server" meta:resourcekey="Address_HouseNumber">
                        <Additions>
                            <mfadd:Restriction runat="server" RestrictionType="MaxLength" Value="10" />
                        </Additions>
                    </mf:Leaf>
                    <mf:Leaf Name="FlatNumber" runat="server" meta:resourcekey="Address_FlatNumber">
                        <Additions>
                            <mfadd:Restriction runat="server" RestrictionType="MaxLength" Value="10" />
                        </Additions>
                    </mf:Leaf>
                    <mf:Leaf Name="PostCode" runat="server" meta:resourcekey="Address_PostCode">
                        <Additions>
                            <mfadd:Restriction runat="server" RestrictionType="Pattern" Value="\d{2}-\d{3}" />
                        </Additions>
                        <ValueHandler>
                            <zh:ZipCodeValueHandler runat="server" Src="ZipCodeControl.ascx" />
                        </ValueHandler>
                    </mf:Leaf>
                    <mf:Leaf Name="Post" runat="server" meta:resourcekey="Address_Post">
                        <Additions>
                            <mfadd:Restriction runat="server" RestrictionType="MaxLength" Value="50" />
                        </Additions>
                    </mf:Leaf>
                    <mf:Leaf Name="City" runat="server" meta:resourcekey="Address_City">
                        <Additions>
                            <mfadd:Restriction runat="server" RestrictionType="MaxLength" Value="50" />
                        </Additions>
                    </mf:Leaf>
                </Contents>
            </mf:Branch>
        </Contents>
        <UriMappings>
            <mf:UriMapping Prefix="xs" Namespace="http://www.w3.org/2001/XMLSchema"></mf:UriMapping>
            <mf:UriMapping Prefix="" Namespace=""></mf:UriMapping>
        </UriMappings>
    </mf:Root>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="Description" runat="server">
    <p>
        MForm is not limited to using standard value handlers. Any webcontrol that provides
        any textual input can be used, if it has an appropriate value handler written.
    </p>
    <p>
        Writing custom value handlers is pretty straightforward. It needs writing a little
        bit of server-side and a little bit of client-side code.
    </p>
    <div class="Section">
        <mftitle:TitleControl runat="server" Text="Implementing value handler on the server side" />
        <p>
            Any value handler must inherit from the <code>ControlValueHandler</code>&lt;<code>TControl</code>&gt;,
            where <code>TControl</code> must inherit from the <code>Control</code>.
        </p>
        <p>
            There are several more specific overrides of the <code>ControlValueHandler</code>
            that are available to the developer:
        </p>
        <ul>
            <li><code>UserControlValueHandler</code>&lt;<code>TUserControl</code>&gt; where <code>
                TUserControl</code> must inherit from <code>UserControl</code></li>
            <li><code>StandardWebControlValueHandler</code>&lt;<code>TWebControl</code>&gt; where
                <code>TWebControl</code> must inherit from <code>WebControl</code></li>
            <li><code>ListControlValueHandler</code>&lt;<code>TListControl</code>&gt; where <code>
                TListControl</code> must inherit from <code>ListControl</code></li>
        </ul>
        <p>
            Each of these handlers provides a <code>Control</code> property, that is of the
            generic type.
        </p>
        <p>
            Each implementation of the value handler on the server side, must implement agetter and setter of the <code>Value</code> property. This implementation usually
            looks like this:
        </p>
        <div class="Remark">
            <p>
<code>
<pre>
public override string Value
{
    get
    {
        return Control.Value;
    }

    set
    {
        Control.Value = value;
    }
}
</pre>
</code>                
            </p>
        </div>
        <p>
            and it depends on the Control's characteristics (remember that the Control type
            is generic).
        </p>
    </div>
    <div class="Section">
        <mftitle:TitleControl runat="server" Text="Implementing value handler on the client side" />
        <p>
            The value handler's client side class must also inherit from the <code>BM.ValueHandler</code>
            javascript class. This can be done with the following code:
        </p>
        <div class="Remark">
            <p>
                <span class="namespace">(SomeCustomValueHandler)</span>.registerClass("<span class="namespace">(SomeCustomValueHandler)</span>",
                <code>BM.ValueHandler</code>);
            </p>
        </div>
        <p>
            Besides that, the value handler must register itself for the value handler's factory
            (the key in this registration is the control's type name):
        </p>
        <div class="Remark">
            <p>
                BM.ValueHandler['<span class="namespace">(server control type name)</span>'] = <span
                    class="namespace">(SomeCustomValueHandler)</span>;
            </p>
        </div>
        <p>
            With the above done, implementing two methods is left:
        </p>
        <ul>
            <li><code>setControlValue</code> method, which sets the control value in javascript</li>
            <li><code>getControlValue</code> method, which gets the value text from the control</li>
        </ul>
        <p>
            The HTML DOM element that is correspondent to the server-side LeafItem is avaliable
            in the value handler class as the <code>this.getLeafNode()</code>.</p>
        <p>
            The implementation of the client side should look like this:
        </p>
        <div class="Remark">
            <pre>
	<span class="namespace">(SomeCustomValueHandler)</span> = function(<code>leafItem</code>) {
		<span class="namespace">(SomeCustomValueHandler)</span>.initializeBase(<code>this</code>, <code>[leafItem]</code>);
	}

	<span class="namespace">(SomeCustomValueHandler)</span>.prototype = {
		<code>getControlValue</code>: function() {
			...
		},

		<code>setControlValue</code>: function(value) {
			...
		}
	}
</pre>
        </div>
    </div>
</asp:Content>
